package com.hunan.api.catv.service.impl.apple;

import com.auth0.jwk.InvalidPublicKeyException;
import com.auth0.jwk.Jwk;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import com.hunan.api.catv.utils.GsonUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.Jwts;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.web.client.RestTemplate;

import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.security.PublicKey;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Service
public class AppleService {

    @Autowired
    RestTemplate restTemplate;

    /**
     * 获取苹果的公钥
     *
     * @return
     */
    public JsonArray getAuthKeys() {
        String url = "https://appleid.apple.com/auth/keys";
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/json");
        headers.add("charset", "UTF-8");
        headers.set(HttpHeaders.ACCEPT_CHARSET, StandardCharsets.UTF_8.toString());
        HttpEntity<String> requestEntity = new HttpEntity<String>("", headers);
        ResponseEntity<String> result = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);
        if (result.getStatusCodeValue() == HttpStatus.OK.value()) {
            JsonObject body = GsonUtils.fromJson(result.getBody(), JsonObject.class);
            return body.get("keys").getAsJsonArray();
        }
        return null;
    }

    public Boolean verify(String jwt) throws InvalidPublicKeyException {
        JsonArray array = getAuthKeys();
        if (ObjectUtils.isEmpty(array)) {
            return false;
        }
        Map<String, Object> authKey = new ConcurrentHashMap<String, Object>();
        Type type = new TypeToken<Map<String, Object>>() {
        }.getType();
        authKey = GsonUtils.fromJson(array.get(0).toString(), type);
        if (verifyExc(jwt, authKey)) {
            return true;
        }
        authKey = GsonUtils.fromJson(array.get(1).toString(), type);
        if (verifyExc(jwt, authKey)) {
            return true;
        }
        return false;
    }

    /**
     * 对前端传来的identityToken进行验证
     *
     * @param jwt     对应前端传来的 identityToken
     * @param authKey 苹果的公钥 authKey
     * @return
     */
    public Boolean verifyExc(String jwt, Map<String, Object> authKey) {
        try {
            Jwk jwa = Jwk.fromValues(authKey);
            PublicKey publicKey = jwa.getPublicKey();

            String aud = "";
            String sub = "";
            if (jwt.split("\\.").length > 1) {
                String claim = new String(Base64.decodeBase64(jwt.split("\\.")[1]));
                aud = GsonUtils.fromJson(claim, JsonObject.class).get("aud").getAsString();
                sub = GsonUtils.fromJson(claim, JsonObject.class).get("sub").getAsString();
            }
            JwtParser jwtParser = Jwts.parser().setSigningKey(publicKey);
            jwtParser.requireIssuer("https://appleid.apple.com");
            jwtParser.requireAudience(aud);
            jwtParser.requireSubject(sub);
            Jws<Claims> claim = jwtParser.parseClaimsJws(jwt);
            if (claim != null && claim.getBody().containsKey("auth_time")) {
                return true;
            }
        } catch (Exception e) {
            return false;
        }
        return false;
    }


    public JsonObject parserIdentityToken(String identityToken) {
        String[] arr = identityToken.split("\\.");
        String decode = new String(Base64.decodeBase64(arr[1]));
        String substring = decode.substring(0, decode.indexOf("}") + 1);
        JsonObject info = GsonUtils.fromJson(substring, JsonObject.class);
        return info;
    }

//    public static void main(String[] args) throws InvalidPublicKeyException {
//    	String jwt = "eyJraWQiOiJlWGF1bm1MIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJodHRwczovL2FwcGxlaWQuYXBwbGUuY29tIiwiYXVkIjoiY29tLmNoaW5hb3R0dHYuc25haWxhcHAiLCJleHAiOjE1OTU5MDQwNzUsImlhdCI6MTU5NTkwMzQ3NSwic3ViIjoiMDAwNzYxLmNhYzAzMWRlZGNmNjQwNmQ5YTFjZjQ4YTViMTJjOTZkLjA4MjIiLCJjX2hhc2giOiJ5dFdRbUJzUkZaTmFUVkhGbHRna0N3IiwiZW1haWwiOiJkajR2ZXBqZm5lQHByaXZhdGVyZWxheS5hcHBsZWlkLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjoidHJ1ZSIsImlzX3ByaXZhdGVfZW1haWwiOiJ0cnVlIiwiYXV0aF90aW1lIjoxNTk1OTAzNDc1LCJub25jZV9zdXBwb3J0ZWQiOnRydWV9.CQqdIsbRsxgG_zHDCiaN1w8z5VXuTduJuGPlVa_vQ_xeLOuIZoGGXWeSQiINvnCgSx0iUmL3X1RiiBEQ6qSRw4Y4f5v3O0l2MAnLAOsTCBdITn9YjiWNDL9jG59xhTeNG3iULT13HQTBW9XL8eamyYVpsosL5k5TMl5nyH3_4nqhY9-WJY6FDdzU9aNpPudwOG7YY92nbW50-3hWqbyTRQmw9ICWlIMgwYdyuhoWcEGDoJ40zQcPpHNBuYM9YJXwW7m1y1i4qkaMrcGnSREPd5iwIEH7NH5WnSlxJJnoT5ME9hBHE4U6w3XMRFVMKYsBvkm2Ht_NWL58Tba9hhhjvA";
//	}

}
